﻿#include "stdafx.h"
#include "fbpMainFrame.h"
#include "SourceView.h"
#include "WatchView.h"

LUA_DEBUG_BEGIN

BEGIN_EVENT_TABLE(fbpMainFrame, MainFrameBase)
EVT_DEBUG_UPDATE_SOURCE(wxID_ANY, fbpMainFrame::OnUpdateSource)
END_EVENT_TABLE()

fbpMainFrame::fbpMainFrame(wxWindow* parent,long ScriptID,const DebugEndCallback_t & cb) :
MainFrameBase(parent),
m_mediator(new Mediator),
m_end_callback(cb),
m_ScriptID(ScriptID)
{
    // 调试代理绑定主窗口
    m_mediator->SetMainFrame(this);
    m_sourceView->SetMediator(m_mediator);

    SetIcon(wxNullIcon);
    CreateDebugWindows();
    Center();
}

fbpMainFrame::~fbpMainFrame(void)
{
    if( m_end_callback )
        m_end_callback(m_ScriptID);

    m_mediator->SetMainFrame(NULL);
}

void fbpMainFrame::ProcessDebugEvent(wxDebugEvent &event, bool sendAlways)
{
    ProcessDebugEvent(event,this,sendAlways);
}

void fbpMainFrame::ProcessDebugEvent(wxDebugEvent &event, wxWindow *parent, bool sendAlways)
{
    if (!sendAlways && !parent->IsShown()) {
        return;
    }

    wxWindowList& children = parent->GetChildren();
    for (size_t i = 0; i < children.GetCount(); ++i) {
        ProcessDebugEvent(event, children[i], sendAlways);
    }

    event.SetId(parent->GetId());
    parent->ProcessWindowEvent(event);
}

bool fbpMainFrame::IsExistDebugWindow(long wintypeid)
{
    return (FindWindowById(wintypeid,this) != NULL);
}

void fbpMainFrame::ShowDebugWindow(long wintypeid) {
    wxAuiNotebook *auiNotebook = m_wathView;
    if (auiNotebook == NULL) {
        return;
    }

    // If the view is already exist, do nothing.
    if (IsExistDebugWindow(wintypeid)) {
        return;
    }

    switch (wintypeid)
    {
    case ID_LOCALWATCHVIEW:
        auiNotebook->AddPage(new WatchView(m_mediator, this,WatchView::TYPE_LOCALWATCH),_("局部变量"));
        break;
    case ID_GLOBALWATCHVIEW:
        auiNotebook->AddPage(new WatchView(m_mediator, this,WatchView::TYPE_GLOBALWATCH),_("全局变量"));
        break;
    case ID_REGISTRYWATCHVIEW:
        auiNotebook->AddPage(new WatchView(m_mediator, this,WatchView::TYPE_REGISTRYWATCH),_("注册类型"));
        break;
    case ID_ENVIRONWATCHVIEW:
        //auiNotebook->AddPage(new WatchView(m_mediator, this,WatchView::TYPE_ENVIRONWATCH),_("注册函数"));
        break;
    case ID_STACKWATCHVIEW:
        auiNotebook->AddPage(new WatchView(m_mediator, this,WatchView::TYPE_STACKWATCH),_("堆栈查看"));
        break;
    case ID_WATCHVIEW:
        //auiNotebook->AddPage(new WatchView(m_mediator, this,WatchView::TYPE_WATCH),_("变量查看"));
        break;
    case ID_BACKTRACEVIEW:
        //auiNotebook->AddPage(new BacktraceView(m_mediator, this),_("跟踪"));
        break;
    case ID_INTERACTIVEVIEW:
        //auiNotebook->AddPage(new InteractiveView(m_mediator, this),_("交互"));
        break;
    case ID_OUTPUTVIEW:
        //auiNotebook->AddPage(new OutputView(m_mediator, this),_("输出"));
        break;
    default:
        return;
    }

    // Select and show new page.
    if (auiNotebook->GetPageCount() > 0) {
        auiNotebook->SetSelection(auiNotebook->GetPageCount() - 1);
    }
}

void fbpMainFrame::CreateDebugWindows()
{
    ShowDebugWindow(ID_LOCALWATCHVIEW);
    ShowDebugWindow(ID_GLOBALWATCHVIEW);
    ShowDebugWindow(ID_REGISTRYWATCHVIEW);
    ShowDebugWindow(ID_ENVIRONWATCHVIEW);
    ShowDebugWindow(ID_STACKWATCHVIEW);
    ShowDebugWindow(ID_WATCHVIEW);
    ShowDebugWindow(ID_BACKTRACEVIEW);
    ShowDebugWindow(ID_INTERACTIVEVIEW);
    ShowDebugWindow(ID_OUTPUTVIEW);

    m_wathView->SetSelection(0);
}

void fbpMainFrame::OnMenu(wxCommandEvent &event)
{
    switch (event.GetId())
    {
    case wxID_EXIT:
        Close(true);
        break;
    case ID_MENU_BREAK:
        m_mediator->GetEngine()->SendBreak();
        break;
    case ID_MENU_RESTART:
        m_mediator->GetEngine()->SendResume();
        break;
    case ID_MENU_STEPOVER:
        m_mediator->GetEngine()->SendStepOver();
        //wxLogMessage("SendStepOver");
        break;
    case ID_MENU_STEPINTO:
        m_mediator->GetEngine()->SendStepInto();
        //wxLogMessage("SendStepInto");
        break;
    case ID_MENU_STEPRETURN:
        m_mediator->GetEngine()->SendStepReturn();
        //wxLogMessage("SendStepReturn");
        break;
    case ID_MENU_TOGGLE_BREAKPOINT:
        m_sourceView->ToggleBreakpoint();
        break;
    case ID_MENU_SHOW_LOCALWATCH:
        ShowDebugWindow(ID_LOCALWATCHVIEW);
        break;
    case ID_MENU_SHOW_GLOBALWATCH:
        ShowDebugWindow(ID_GLOBALWATCHVIEW);
        break;
    case ID_MENU_SHOW_REGISTRYWATCH:
        ShowDebugWindow(ID_REGISTRYWATCHVIEW);
        break;
    case ID_MENU_SHOW_ENVIRONWATCH:
        ShowDebugWindow(ID_ENVIRONWATCHVIEW);
        break;
    case ID_MENU_SHOW_STACKWATCH:
        ShowDebugWindow(ID_STACKWATCHVIEW);
        break;
    case ID_MENU_SHOW_WATCH:
        ShowDebugWindow(ID_WATCHVIEW);
        break;
    case ID_MENU_SHOW_BACKTRACEVIEW:
        ShowDebugWindow(ID_BACKTRACEVIEW);
        break;
    case ID_MENU_SHOW_INTERACTIVEVIEW:
        ShowDebugWindow(ID_INTERACTIVEVIEW);
        break;
    }
}

void fbpMainFrame::OnUpdateSource(wxDebugEvent &event)
{
    wxUnusedVar(event);
    Raise();
}

void fbpMainFrame::OnIdle(wxIdleEvent &event)
{
    if( event.GetId() == wxID_ANY ){
        m_mediator->ProcessAllRemoteCommands();
    }
}

LUA_DEBUG_END
